/*
 *  ReadAst.cpp
 *  TempWorking
 *
 *  Created by Piotr Holc on 20/11/2010.
 *  Copyright 2010 Langerra Limited. All rights reserved.
 *
 */

#include <MAlice/Ast/ReadAst.h>
#include <MAlice/Ast/CastBooleanAst.h>
#include <MAlice/Ast/IfStatementAst.h>
#include <MAlice/Ast/ConditionalExpressionAst.h>
#include <MAlice/Ast/IntegerLiteralAst.h>
#include <MAlice/Parser/location.hh>

namespace MAlice
{

ReadAst::ReadAst(location loc, VariableAst* var) :
	ExpressionAst(loc), mVar(var)
{
	MALICE_TRACE;
}

ReadAst::~ReadAst()
{
	MALICE_TRACE;
}

llvm::Value* ReadAst::generate()
{

	MALICE_TRACE;
	// Global Variable Declarations
	Codegen *g = Codegen::get();
	Module *mod = g->getModule();
	Builder *builder = g->getBuilder();

	std::vector<Value*> params;

	GlobalVariable* fmt = mod->getGlobalVariable(".fmt_d", true);

	ConstantInt* unbound = ConstantInt::get(
			Type::getInt64Ty(mod->getContext()), "0", 10);

	vector<Constant*> indicies;
	indicies.push_back(unbound);
	indicies.push_back(unbound);

	Constant* format = ConstantExpr::getGetElementPtr(fmt, &indicies[0],
			indicies.size());

	params.push_back(format);
	params.push_back(mVar->getPointer());

	CallInst* results = builder->CreateCall(mod->getFunction("scanf"),
			params.begin(), params.end());
	results->setCallingConv(CallingConv::C);
	results->setTailCall(false);

	AttrListPtr attrs;
	{
		SmallVector<AttributeWithIndex, 4> Attrs;
		AttributeWithIndex PAWI;
		PAWI.Index = 1U;
		PAWI.Attrs = 0 | Attribute::NoAlias;
		Attrs.push_back(PAWI);
		PAWI.Index = 4294967295U;
		PAWI.Attrs = 0 | Attribute::NoUnwind;
		Attrs.push_back(PAWI);
		attrs = AttrListPtr::get(Attrs.begin(), Attrs.end());

	}
	results->setAttributes(attrs);

	/*
	 * TODO
	 * if ( 1 != results )
	 * 	puts("IOError: Could not read integer from standard input!");
	 * 	abort();
	 IfStatementAst(
	 new ConditionalExpressionAst(
	 new BinaryInEqualityOperatorAst(
	 new IntegerLiteralAst(1),
	 results),
	 XXX BODY
	 ));
	 */

	return results;
}

}
